﻿/*++

Copyright (c) 2011 Rainr Corporation

Module Name:

	Rainr.Utilities.Collections.ListDictionary<TKey,TValue>

Abstract:

	顺序存储的KV字典 

Author:

	Zhou Junyu (Rainr)    2011-01-01

Revision History:
  
--*/

using System;
using System.Collections;
using System.Collections.Generic;

namespace Rainr.Utilities.Collections
{
    /// <summary>
    /// 顺序存储的KV字典
    /// </summary>
    /// <typeparam name="TKey">TKey</typeparam>
    /// <typeparam name="TValue">TValue</typeparam>
    [Serializable]
    public class ListDictionary<TKey, TValue> : IDictionary<TKey, TValue>
    {
        protected IList<TKey> keys = null;
        protected Hashtable values = null;

        public ListDictionary(int capacity)
        {
            this.keys = new List<TKey>(capacity);
            this.values = new Hashtable(capacity);
        }
        public ListDictionary()
            : this(0)
        {
        }

        public void Add(TKey key, TValue value)
        {
            if (this.keys.Contains(key))
            {
                this.values[key] = value;
            }
            else
            {
                lock (this)
                {
                    this.keys.Add(key);
                    this.values.Add(key, value);
                }
            }
        }

        public void Add(KeyValuePair<TKey, TValue> item)
        {
            this.Add(item.Key, item.Value);
        }

        public TValue this[TKey key]
        {
            get
            {
                return (TValue)this.values[key];
            }
            set
            {
                this.Add(key, value);
            }
        }

        public bool Remove(TKey key)
        {
            lock (this)
            {
                this.values.Remove(key);
                return this.keys.Remove(key);
            }
        }

        public bool Remove(KeyValuePair<TKey, TValue> item)
        {
            if (this.Contains(item))
                return this.Remove(item.Key);
            return false;
        }

        public void Clear()
        {
            lock (this)
            {
                this.values.Clear();
                this.keys.Clear();
            }
        }

        public bool TryGetValue(TKey key, out TValue value)
        {
            if (this.keys.Contains(key))
            {
                value = (TValue)this.values[key];
                return true;
            }
            value = default(TValue);
            return false;
        }

        public ICollection<TKey> Keys
        {
            get { return this.keys; }
        }
        public ICollection<TValue> Values
        {
            get
            {
                return this.getValueList();
            }
        }

        public bool ContainsKey(TKey key)
        {
            return this.keys.Contains(key);
        }
        public bool Contains(KeyValuePair<TKey, TValue> item)
        {
            if (this.keys.Contains(item.Key) && item.Value.Equals(this.values[item.Key]))
            {
                return true;
            }
            return false;
        }

        public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
        {
            KeyValuePair<TKey, TValue>[] arraytemp = null;
            if ((array.Length - 1 - arrayIndex) < this.keys.Count)
            {
                arraytemp = new KeyValuePair<TKey, TValue>[arrayIndex + this.keys.Count];
            }
            else
            {
                arraytemp = array;
            }
            foreach (TKey key in this.keys)
            {
                arraytemp[arrayIndex++] = new KeyValuePair<TKey, TValue>(key, (TValue)this.values[key]);
            }
            array = arraytemp;
        }

        public int Count
        {
            get { return this.keys.Count; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        [Obsolete]
        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
        {
            return null;
        }
        [Obsolete]
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return null;
        }

        private IList<TValue> getValueList()
        {
            IList<TValue> valueList = new List<TValue>(this.keys.Count);
            int index = 0;
            foreach (TKey key in this.keys)
            {
                valueList[index++] = (TValue)this.values[key];
            }
            return valueList;
        }

    }
}
